package com.imooc.bilibili.aspect;

import com.imooc.bilibili.annotation.ApiLimitedRole;
import com.imooc.bilibili.constant.AuthRoleConstant;
import com.imooc.bilibili.domain.UserMoment;
import com.imooc.bilibili.domain.auth.UserRole;
import com.imooc.bilibili.exception.ConditionException;
import com.imooc.bilibili.service.UserRoleService;
import com.imooc.bilibili.support.UserSupport;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 切面类
 *
 * @author xiexu
 * @create 2022-06-17 07:37
 */
@Aspect // 表明这是一个切面类
@Order(1) // 优先级
@Component // 让spring容器扫描到
public class DataLimitedAspect {

    @Autowired
    private UserSupport userSupport;

    @Autowired
    private UserRoleService userRoleService;

    /**
     * 切入点
     */
    @Pointcut("@annotation(com.imooc.bilibili.annotation.DataLimited)")
    public void check() {
    }

    /**
     * 前置通知
     *
     * @param joinPoint
     */
    @Before("check()")
    public void doBefore(JoinPoint joinPoint) {
        Long userId = userSupport.getCurrentUserId();
        // 获取用户相关的角色列表（用户具有哪些角色）
        List<UserRole> userRoleList = userRoleService.getUseRoleByUserId(userId);
        // 将用户角色列表转换成set集合
        Set<String> roleCodeSet = new HashSet<>();
        for (UserRole userRole : userRoleList) {
            roleCodeSet.add(userRole.getRoleCode());
        }
        // 把切到的方法里面的参数获取到，也就是addUserMoments(@RequestBody UserMoment userMoment)方法的userMoment参数
        Object[] args = joinPoint.getArgs();
        for (Object arg : args) {
            if (arg instanceof UserMoment) {
                UserMoment userMoment = (UserMoment) arg;
                String type = userMoment.getType();
                // 用户角色为lv0的情况下，只能传参"0"给type字段，其他数字参数都报错
                if (roleCodeSet.contains(AuthRoleConstant.ROLE_LV0) && !"0".equals(type)) {
                    throw new ConditionException("参数异常！");
                }
                // 用户角色为lv1的情况下，只能传参"0"或者"1"给type字段，其他数字参数都报错
                if (roleCodeSet.contains(AuthRoleConstant.ROLE_LV1) && (!"1".equals(type) || !"0".equals(type))) {
                    throw new ConditionException("参数异常！");
                }
            }
        }
    }

}
